<script setup>
import { onMounted, ref } from 'vue'
import TableColumn from './TableColumn.vue'
import ColumnSetting from './ColumnSetting.vue'

const superTable = inject('superTable')
const { columns, data, pagination, tableRef, formRef, headerBtn, loading, columnSettingVisible } = toRefs(superTable.table)

onMounted(() => {
    if (pagination.value.position == undefined) pagination.value.position = 'right'

    // 初始化列
    const initColumns = data => {
        data.forEach(item => {
            if (item.typeConfig == undefined) item.typeConfig = {}
            if (item.type == undefined) item.type = 'text'
            if (item.align == undefined) item.align = 'center'
            if (item.visible == undefined) item.visible = true
            if (item.fixed == undefined) item.fixed = false
            if (item.resizable == undefined) item.resizable = true
            if (item.type == 'index') {
                if (item.typeConfig.type == undefined) {
                    item.typeConfig.type = 1
                }
            }
            if (item.children) {
                initColumns(item.children)
            }
        })
    }
    initColumns(columns.value)
})

watch(
    () => [pagination.value.page, pagination.value.pageSize],
    (newVal, oldVal) => {
        superTable.getList()
    }
)

const showIndexAdd = ref(false)
const showIndexDel = ref(false)
const indexRow = ref(null)
const cellMouseEnter = (row, column, cell, event) => {
    indexRow.value = row
}
const cellMouseLeave = (row, column, cell, event) => {
    indexRow.value = null
}
const addIndex = (index, row) => {
    let newRow = JSON.parse(JSON.stringify(row))
    for (let k in newRow) {
        switch (typeof newRow[k]) {
            case 'number':
                newRow[k] = 0
                break
            case 'string':
                newRow[k] = ''
                break
            case 'boolean':
                newRow[k] = false
                break
            case 'object':
                newRow[k] = {}
                break
            case 'array':
                newRow[k] = []
                break
            default:
                break
        }
    }
    data.value.splice(index + 1, 0, newRow)
}
const delIndex = (index, row) => {
    data.value.splice(index, 1)
}
</script>

<template>
    <div class="dynamic-table">
        <div class="header-btn" :style="headerBtn.style">
            <template v-if="headerBtn.type == 'headerBtn'">
                <el-button type="primary" @click="superTable.save(formRef)">保存</el-button>
                <el-button type="primary" @click="superTable.getList">查询</el-button>
                <el-button type="" @click="superTable.flushTable">刷新</el-button>
                <el-button type="" @click="superTable.handleColumnSetting">列设置</el-button>
            </template>
            <template v-else="headerBtn.type">
                <slot :name="headerBtn.type" />
            </template>
        </div>
        <column-setting v-model:visible="columnSettingVisible" v-model="columns" />

        <el-form :model="data" ref="formRef">
            <el-table
                :data="data"
                @selection-change="superTable.selectionChange"
                :ref="tableRef"
                v-loading="loading"
                border
                @cell-mouse-enter="cellMouseEnter"
                @cell-mouse-leave="cellMouseLeave"
            >
                <template v-for="col in columns" :key="col.prop">
                    <el-table-column v-if="col.type === 'selection'" type="selection" :align="col.align" :width="col.width" />
                    <el-table-column
                        v-else-if="col.type === 'index'"
                        type="index"
                        :prop="col.prop"
                        :label="col.label"
                        :align="col.align"
                        :width="col.width"
                        :fixed="col.fixed"
                    >
                        <template #default="{ row, $index }">
                            <span v-if="col.typeConfig.type == 1">{{ $index + 1 + (pagination.page - 1) * pagination.pageSize }}</span>
                            <span v-else-if="col.typeConfig.type == 2">{{ $index + 1 }}</span>
                            <div v-else="col.typeConfig.type == 3">
                                <div v-if="row == indexRow" class="index-tag">
                                    <div v-if="['all', 'add'].includes(col.typeConfig.showType)" class="add-tag-btn" @click="addIndex($index, row)">+</div>
                                    <div v-if="['all', 'del'].includes(col.typeConfig.showType)" class="add-tag-btn del-tag-btn" @click="delIndex($index, row)">
                                        -
                                    </div>
                                </div>
                                <div v-else class="index-tag-btn">{{ $index + 1 }}</div>
                            </div>
                        </template>
                    </el-table-column>
                    <table-column v-else :col="col" v-if="col.visible">
                        <template #children>
                            <template v-for="col2 in col.children" :key="col2.prop">
                                <table-column :col="col2" v-if="col2.visible">
                                    <template #[col2.type]="{ scope, colSlot }">
                                        <slot v-if="col2.type" :name="col2.type" :scope="scope" :col="col2" />
                                    </template>
                                </table-column>
                            </template>
                        </template>
                        <template #[col.type]="{ scope, colSlot }">
                            <slot :name="col.type" :scope="scope" :col="col" />
                        </template>
                    </table-column>
                </template>
            </el-table>
        </el-form>
        <div :class="['pagination', pagination.position]" :style="pagination.style">
            <el-pagination
                v-if="pagination.status"
                v-model:current-page="pagination.page"
                v-model:page-size="pagination.pageSize"
                :total="pagination.total"
                :background="pagination.background"
                :layout="pagination.layout"
                :page-sizes="pagination.pageSizes"
            />
        </div>
    </div>
</template>

<style scoped lang="scss">
.dynamic-table {
    width: 100%;
}
.header-btn {
    padding: 10px 0;
}
.pagination {
    padding: 10px 0;
    display: flex;
    align-items: center;
}
.left {
    justify-content: flex-start;
}
.center {
    justify-content: center;
}
.right {
    justify-content: flex-end;
}
.index-tag {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    .add-tag-btn {
        width: 20px;
        height: 20px;
        min-width: 20px;
        border-radius: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: #4ab616;
        font-size: 12px;
        color: #fff;
        font-weight: bold;
        cursor: pointer;
    }
    .del-tag-btn {
        background-color: #ff4d4f;
        cursor: pointer;
        margin-left: 5px;
    }
}
</style>
